#include "PointProtocol.h"
#include <QDebug>

PointProtocol::PointProtocol(QObject *parent) :
    BaseProtocol(parent)
{
    this->m_protocolType = ProtocolType::PointProtocol;
}

QList<Package> PointProtocol::parseData(QByteArray data)
{
    CheckSteps checkSteps = CHECK_HEAD;  //当前解析状态
    quint16  lengthCount = 0;      //数据长度计算
    quint16  dataLength = 0;
    quint8  lengthCheckSum = 0;
    quint8  dataCheckSum = 0;
    Package package;
    QByteArray dataArray;

    QList<Package> packageList;
 //  qDebug()<<"PointProtocol now.................."<<data.size();
    for(int i=0; i<data.size(); i++)
    {

        quint8 byte = data.at(i);

        switch(checkSteps)
        {
            case CHECK_HEAD:   //检查数据头
                 if(byte == 0XEE)
                 {
                     lengthCount = 0;
                     dataLength = 0;
                     lengthCheckSum = 0;
                     dataCheckSum = 0;
                     package.clear();

                     dataArray.clear();
                     dataArray.append(byte);

                     checkSteps = CHECK_LENGTH;
                 }
            break;

            case CHECK_LENGTH:  //接收数据长度
                 dataArray.append(byte);
                 lengthCount++;
                 if(lengthCount == 1)
                 {
                     dataLength = (quint16)byte << 8;
                     lengthCheckSum += dataLength;
                 }
                 if(lengthCount == 2)
                 {
                     lengthCount = 0;
                     dataLength |= byte;
                     lengthCheckSum += dataLength;

                     checkSteps = CHECK_LENGHTSUM;
                 }
                 break;

            case CHECK_LENGHTSUM:    //检查数据长度校验
                 if((lengthCheckSum == byte)&&(byte<50))
                 {
                     dataArray.append(byte);
                     checkSteps = CHECK_BODY;
                 }
                 else
                 {
                     checkSteps = CHECK_HEAD;
                     i-=3;
                 }
                 break;


            case CHECK_BODY:   //接收数据内容
                 dataArray.append(byte);
                 dataCheckSum += byte;
                 lengthCount++;
                 if(lengthCount >= dataLength)
                 {
                     lengthCount = 0;
                     checkSteps = CHECK_CHECKCODE;
                 }

            break;

            case CHECK_CHECKCODE:  //检查数据校验
                 if(dataCheckSum == byte)
                 {
                     dataArray.append(byte);
                     checkSteps = CHECK_END;
                 }
                 else checkSteps = CHECK_HEAD;
            break;

            case CHECK_END:    //检查数据尾
                 if(byte == 0xFE)
                 {
                     dataArray.append(byte);
                     package.setHead(dataArray.mid(0,1));
                     package.setLength(dataLength);
                     package.setCheckCode(dataCheckSum);
                     package.setTail(dataArray.mid(5+dataLength,1));

                     int type = dataArray.mid(4,2).toHex().toInt(0,16);
                     if(type == 0x0F80)
                     {
                         int function = type;
                         package.setFunction(function);
                         package.setBody(dataArray.mid(6,dataLength-2));

                          qDebug()<<"type==0F80 now-------------------";
                     }
                     else if(type == 0x0D10)
                     {
                         int function = dataArray.mid(4,4).toHex().toInt(0,16);
                         package.setFunction(function);
                         package.setBody(dataArray.mid(8,dataLength-4));
                     }
                     else if(type == 0x0F81)
                     {
                         int function = dataArray.mid(4,2).toHex().toInt(0,16);
                         package.setFunction(function);
                         package.setBody(dataArray.mid(6,dataLength));
           //              qDebug()<<"come 0F81";
                     }

                     packageList.append(package);
                 }
                 checkSteps = CHECK_HEAD;
            break;
        }
    }
    return packageList;
}

QByteArray PointProtocol::generateData(Package package)
{



    quint16 length=0,functionCodeLength=0;
    quint32 functionCode = package.function();
    quint32 tempFunctionCod = functionCode >> 16;
    if(functionCode == 0x0F80)
    {
        functionCodeLength = 2;
        length = functionCodeLength + package.body().size();
    }
    else if(tempFunctionCod == 0x0D10)
    {
        functionCodeLength = 4;
        length = functionCodeLength + package.body().size();
    }
    else if(tempFunctionCod == 0x0F81)
    {
        functionCodeLength = 2;
        length = functionCodeLength + package.body().size();
        tempFunctionCod=0x0F82;
    }

    QByteArray data;
    data.append(0xEE);
    data.append(DataTypeConver::intToByteArray(length,2));
    data.append((length >>8) + (length & 0xFF));
    data.append(DataTypeConver::intToByteArray(functionCode,functionCodeLength));
    data.append(package.body());
    quint8 checkcode = CheckCode::computeSum(data,4,data.size());
    data.append(checkcode);
    data.append(0xFE);
    return data;
}

QByteArray PointProtocol::getPointData(quint16 function,quint16 addr,quint16 value)
{
    QByteArray SetPointData;
    SetPointData.resize(12);
    SetPointData[0]=0xEE;
    SetPointData[1]=0x00;
    SetPointData[2]=0x06;
    SetPointData[3]=0x06;
    SetPointData[4]=(function &0xff00)>>8;
    SetPointData[5]=function &0xff;
    SetPointData[6]=(addr &0xff00)>>8;
    SetPointData[7]=addr &0xff;
    SetPointData[8]=(value &0xff00)>>8;
    SetPointData[9]=value &0xff;
    quint16 CheckCode=(SetPointData[4]+SetPointData[5]+SetPointData[6]+SetPointData[7]+SetPointData[8]+SetPointData[9])&0xff;
    SetPointData[10]=CheckCode;
    SetPointData[11]=0xFE;
    return SetPointData;
}



